using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;
using System.Threading.Tasks;
using System.Text.Json;
using System.Net.Http;
using System;
using System.Collections.Generic;
using System.Linq;

namespace JGSY.CMS.LowCode.Platform.Application.Services
{
    /// <summary>
    /// 社交认证应用服务
    /// 提供社交平台认证、绑定、解绑等第三方认证相关业务功能
    /// </summary>
    public class SocialAuthAppService : ISocialAuthAppService
    {
        private readonly ILogger<SocialAuthAppService> _logger;
        private readonly IConfiguration _configuration;
        private readonly HttpClient _httpClient;

        /// <summary>
        /// 构造函数，注入必要的依赖服务
        /// </summary>
        /// <param name="logger">日志服务</param>
        /// <param name="configuration">配置服务</param>
        /// <param name="httpClient">HTTP客户端</param>
        public SocialAuthAppService(
            ILogger<SocialAuthAppService> logger,
            IConfiguration configuration,
            HttpClient httpClient)
        {
            _logger = logger;
            _configuration = configuration;
            _httpClient = httpClient;
        }

        /// <summary>
        /// 获取社交平台配置信息
        /// </summary>
        /// <returns>社交配置数据传输对象</returns>
        public async Task<SocialConfigDto> GetSocialConfigAsync()
        {
            try
            {
                _logger.LogInformation("获取社交平台配置信息");

                await Task.CompletedTask; // 异步方法占位

                var config = new SocialConfigDto
                {
                    GithubEnabled = _configuration.GetValue<bool>("Social:GitHub:Enabled", false),
                    GoogleEnabled = _configuration.GetValue<bool>("Social:Google:Enabled", false),
                    GithubClientId = _configuration.GetValue<string>("Social:GitHub:ClientId", string.Empty),
                    GoogleClientId = _configuration.GetValue<string>("Social:Google:ClientId", string.Empty)
                };

                _logger.LogInformation("成功获取社交平台配置，GitHub启用: {GithubEnabled}, Google启用: {GoogleEnabled}",
                    config.GithubEnabled, config.GoogleEnabled);

                return config;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取社交平台配置失败");
                throw;
            }
        }

        /// <summary>
        /// GitHub 认证回调处理
        /// </summary>
        /// <param name="code">GitHub 返回的授权码</param>
        /// <param name="state">状态参数</param>
        /// <returns>认证令牌</returns>
        public async Task<string> GithubCallbackAsync(string code, string state)
        {
            try
            {
                _logger.LogInformation("处理GitHub认证回调，Code: {Code}, State: {State}", code, state);

                // 获取GitHub配置
                var clientId = _configuration.GetValue<string>("Social:GitHub:ClientId");
                var clientSecret = _configuration.GetValue<string>("Social:GitHub:ClientSecret");

                if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret))
                {
                    throw new InvalidOperationException("GitHub OAuth配置不完整");
                }

                // 第一步：使用授权码获取访问令牌
                var tokenResponse = await GetGithubAccessTokenAsync(code, clientId, clientSecret);

                // 第二步：使用访问令牌获取用户信息
                var userInfo = await GetGithubUserInfoAsync(tokenResponse.AccessToken);

                // 第三步：处理用户登录或注册逻辑
                var jwtToken = GenerateJwtToken("github", userInfo.Login, userInfo.Id.ToString());

                _logger.LogInformation("GitHub认证回调处理成功，用户: {Login}, ID: {Id}", userInfo.Login, userInfo.Id);
                return jwtToken;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "GitHub认证回调处理失败，Code: {Code}", code);
                throw;
            }
        }

        /// <summary>
        /// Google 认证回调处理
        /// </summary>
        /// <param name="code">Google 返回的授权码</param>
        /// <param name="state">状态参数</param>
        /// <returns>认证令牌</returns>
        public async Task<string> GoogleCallbackAsync(string code, string state)
        {
            try
            {
                _logger.LogInformation("处理Google认证回调，Code: {Code}, State: {State}", code, state);

                // 获取Google配置
                var clientId = _configuration.GetValue<string>("Social:Google:ClientId");
                var clientSecret = _configuration.GetValue<string>("Social:Google:ClientSecret");
                var redirectUri = _configuration.GetValue<string>("Social:Google:RedirectUri");

                if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret))
                {
                    throw new InvalidOperationException("Google OAuth配置不完整");
                }

                // 第一步：使用授权码获取访问令牌
                var tokenResponse = await GetGoogleAccessTokenAsync(code, clientId, clientSecret, redirectUri ?? "");

                // 第二步：使用访问令牌获取用户信息
                var userInfo = await GetGoogleUserInfoAsync(tokenResponse.AccessToken);

                // 第三步：处理用户登录或注册逻辑
                var jwtToken = GenerateJwtToken("google", userInfo.Name, userInfo.Id);

                _logger.LogInformation("Google认证回调处理成功，用户: {Name}, Email: {Email}", userInfo.Name, userInfo.Email);
                return jwtToken;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Google认证回调处理失败，Code: {Code}", code);
                throw;
            }
        }

        /// <summary>
        /// 绑定社交账户
        /// </summary>
        /// <param name="provider">社交平台提供商</param>
        /// <param name="code">授权码</param>
        /// <returns>绑定结果</returns>
        public async Task<string> BindAsync(string provider, string code)
        {
            try
            {
                _logger.LogInformation("开始绑定社交账户，Provider: {Provider}, Code: {Code}", provider, code);

                // 验证提供商参数
                var supportedProviders = new[] { "github", "google", "weibo", "dingtalk", "wechat", "qq" };
                if (!supportedProviders.Contains(provider.ToLower()))
                {
                    throw new ArgumentException($"不支持的社交平台: {provider}");
                }

                if (string.IsNullOrEmpty(code))
                {
                    throw new ArgumentException("授权码不能为空");
                }

                // 模拟绑定过程
                await Task.Delay(100); // 模拟异步操作

                // 根据不同的提供商处理绑定逻辑
                var result = provider.ToLower() switch
                {
                    "github" => await BindGithubAccountAsync(code),
                    "google" => await BindGoogleAccountAsync(code),
                    "weibo" => await BindWeiboAccountAsync(code),
                    "dingtalk" => await BindDingTalkAccountAsync(code),
                    "wechat" => await BindWeChatAccountAsync(code),
                    "qq" => await BindQQAccountAsync(code),
                    _ => throw new NotSupportedException($"不支持的社交平台: {provider}")
                };

                _logger.LogInformation("成功绑定社交账户，Provider: {Provider}, Result: {Result}", provider, result);
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "绑定社交账户失败，Provider: {Provider}, Code: {Code}", provider, code);
                throw;
            }
        }

        /// <summary>
        /// 解绑社交账户
        /// </summary>
        /// <param name="provider">社交平台提供商</param>
        /// <returns>解绑结果</returns>
        public async Task<string> UnbindAsync(string provider)
        {
            try
            {
                _logger.LogInformation("开始解绑社交账户，Provider: {Provider}", provider);

                // 验证提供商参数
                var supportedProviders = new[] { "github", "google", "weibo", "dingtalk", "wechat", "qq" };
                if (!supportedProviders.Contains(provider.ToLower()))
                {
                    throw new ArgumentException($"不支持的社交平台: {provider}");
                }

                // 模拟解绑过程
                await Task.Delay(50); // 模拟异步操作

                // 这里应该是从数据库中删除用户与社交平台的绑定关系
                // 简化实现，直接返回成功消息
                var result = $"{provider} 账号解绑成功";

                _logger.LogInformation("成功解绑社交账户，Provider: {Provider}", provider);
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "解绑社交账户失败，Provider: {Provider}", provider);
                throw;
            }
        }

        /// <summary>
        /// 微博登录认证
        /// </summary>
        /// <param name="code">微博授权码</param>
        /// <returns>认证令牌</returns>
        public async Task<string> LoginWithWeiboAsync(string code)
        {
            try
            {
                _logger.LogInformation("开始微博登录认证，Code: {Code}", code);

                if (string.IsNullOrEmpty(code))
                {
                    throw new ArgumentException("微博授权码不能为空");
                }

                // 获取微博配置
                var appKey = _configuration.GetValue<string>("Social:Weibo:AppKey");
                var appSecret = _configuration.GetValue<string>("Social:Weibo:AppSecret");
                var redirectUri = _configuration.GetValue<string>("Social:Weibo:RedirectUri");

                if (string.IsNullOrEmpty(appKey) || string.IsNullOrEmpty(appSecret))
                {
                    throw new InvalidOperationException("微博OAuth配置不完整");
                }

                // 第一步：使用授权码获取访问令牌
                var tokenResponse = await GetWeiboAccessTokenAsync(code, appKey, appSecret, redirectUri ?? "");

                // 第二步：使用访问令牌获取用户信息
                var userInfo = await GetWeiboUserInfoAsync(tokenResponse.AccessToken, tokenResponse.Uid);

                // 第三步：处理用户登录或注册逻辑
                var jwtToken = GenerateJwtToken("weibo", userInfo.ScreenName, userInfo.Id);

                _logger.LogInformation("微博登录认证成功，Uid: {Uid}, 用户名: {ScreenName}", userInfo.Id, userInfo.ScreenName);
                return jwtToken;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "微博登录认证失败，Code: {Code}", code);
                throw;
            }
        }

        /// <summary>
        /// 钉钉登录认证
        /// </summary>
        /// <param name="code">钉钉授权码</param>
        /// <returns>认证令牌</returns>
        public async Task<string> LoginWithDingTalkAsync(string code)
        {
            try
            {
                _logger.LogInformation("开始钉钉登录认证，Code: {Code}", code);

                if (string.IsNullOrEmpty(code))
                {
                    throw new ArgumentException("钉钉授权码不能为空");
                }

                // 获取钉钉配置
                var appKey = _configuration.GetValue<string>("Social:DingTalk:AppKey");
                var appSecret = _configuration.GetValue<string>("Social:DingTalk:AppSecret");
                var redirectUri = _configuration.GetValue<string>("Social:DingTalk:RedirectUri");

                if (string.IsNullOrEmpty(appKey) || string.IsNullOrEmpty(appSecret))
                {
                    throw new InvalidOperationException("钉钉OAuth配置不完整");
                }

                // 第一步：使用授权码获取用户访问令牌
                var accessToken = await GetDingTalkAccessTokenAsync(code, appKey, appSecret, redirectUri ?? "");

                // 第二步：使用访问令牌获取用户信息
                var userInfo = await GetDingTalkUserInfoAsync(accessToken, appKey, appSecret);

                // 第三步：处理用户登录或注册逻辑
                var jwtToken = GenerateJwtToken("dingtalk", userInfo.Name, userInfo.OpenId);

                _logger.LogInformation("钉钉登录认证成功，OpenId: {OpenId}, 用户名: {Name}", userInfo.OpenId, userInfo.Name);
                return jwtToken;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "钉钉登录认证失败，Code: {Code}", code);
                throw;
            }
        }

        #region 私有辅助方法

        /// <summary>
        /// 获取GitHub访问令牌
        /// </summary>
        /// <param name="code">授权码</param>
        /// <param name="clientId">客户端ID</param>
        /// <param name="clientSecret">客户端密钥</param>
        /// <returns>令牌响应</returns>
        private async Task<GitHubTokenResponse> GetGithubAccessTokenAsync(string code, string clientId, string clientSecret)
        {
            try
            {
                var tokenUrl = "https://github.com/login/oauth/access_token";

                var parameters = new Dictionary<string, string>
                {
                    ["client_id"] = clientId,
                    ["client_secret"] = clientSecret,
                    ["code"] = code
                };

                var content = new FormUrlEncodedContent(parameters);
                var request = new HttpRequestMessage(HttpMethod.Post, tokenUrl)
                {
                    Content = content
                };

                request.Headers.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

                var response = await _httpClient.SendAsync(request);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取GitHub访问令牌失败: {response.StatusCode}, {errorContent}");
                }

                var jsonContent = await response.Content.ReadAsStringAsync();
                var tokenResponse = JsonSerializer.Deserialize<GitHubTokenResponse>(jsonContent);

                if (tokenResponse == null || string.IsNullOrEmpty(tokenResponse.AccessToken))
                {
                    throw new InvalidOperationException("获取GitHub访问令牌失败: 响应格式无效");
                }

                return tokenResponse;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取GitHub访问令牌失败");
                throw;
            }
        }

        /// <summary>
        /// 获取GitHub用户信息
        /// </summary>
        /// <param name="accessToken">访问令牌</param>
        /// <returns>用户信息</returns>
        private async Task<GitHubUserInfo> GetGithubUserInfoAsync(string accessToken)
        {
            try
            {
                var userInfoUrl = "https://api.github.com/user";

                var request = new HttpRequestMessage(HttpMethod.Get, userInfoUrl);
                request.Headers.Add("Authorization", $"token {accessToken}");
                request.Headers.Add("User-Agent", "JGSY-LowCode-Platform");

                var response = await _httpClient.SendAsync(request);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取GitHub用户信息失败: {response.StatusCode}, {errorContent}");
                }

                var jsonContent = await response.Content.ReadAsStringAsync();
                var userInfo = JsonSerializer.Deserialize<GitHubUserInfo>(jsonContent);

                if (userInfo == null)
                {
                    throw new InvalidOperationException("获取GitHub用户信息失败: 响应格式无效");
                }

                return userInfo;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取GitHub用户信息失败");
                throw;
            }
        }

        /// <summary>
        /// 获取Google访问令牌
        /// </summary>
        /// <param name="code">授权码</param>
        /// <param name="clientId">客户端ID</param>
        /// <param name="clientSecret">客户端密钥</param>
        /// <param name="redirectUri">重定向URI</param>
        /// <returns>令牌响应</returns>
        private async Task<GoogleTokenResponse> GetGoogleAccessTokenAsync(string code, string clientId, string clientSecret, string redirectUri)
        {
            try
            {
                var tokenUrl = "https://oauth2.googleapis.com/token";

                var parameters = new Dictionary<string, string>
                {
                    ["client_id"] = clientId,
                    ["client_secret"] = clientSecret,
                    ["code"] = code,
                    ["redirect_uri"] = redirectUri,
                    ["grant_type"] = "authorization_code"
                };

                var content = new FormUrlEncodedContent(parameters);
                var response = await _httpClient.PostAsync(tokenUrl, content);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取Google访问令牌失败: {response.StatusCode}, {errorContent}");
                }

                var jsonContent = await response.Content.ReadAsStringAsync();
                var tokenResponse = JsonSerializer.Deserialize<GoogleTokenResponse>(jsonContent);

                if (tokenResponse == null || string.IsNullOrEmpty(tokenResponse.AccessToken))
                {
                    throw new InvalidOperationException("获取Google访问令牌失败: 响应格式无效");
                }

                return tokenResponse;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取Google访问令牌失败");
                throw;
            }
        }

        /// <summary>
        /// 获取Google用户信息
        /// </summary>
        /// <param name="accessToken">访问令牌</param>
        /// <returns>用户信息</returns>
        private async Task<GoogleUserInfo> GetGoogleUserInfoAsync(string accessToken)
        {
            try
            {
                var userInfoUrl = "https://www.googleapis.com/oauth2/v2/userinfo";

                var request = new HttpRequestMessage(HttpMethod.Get, userInfoUrl);
                request.Headers.Add("Authorization", $"Bearer {accessToken}");

                var response = await _httpClient.SendAsync(request);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取Google用户信息失败: {response.StatusCode}, {errorContent}");
                }

                var jsonContent = await response.Content.ReadAsStringAsync();
                var userInfo = JsonSerializer.Deserialize<GoogleUserInfo>(jsonContent);

                if (userInfo == null)
                {
                    throw new InvalidOperationException("获取Google用户信息失败: 响应格式无效");
                }

                return userInfo;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取Google用户信息失败");
                throw;
            }
        }

        /// <summary>
        /// 获取微博访问令牌
        /// </summary>
        /// <param name="code">授权码</param>
        /// <param name="appKey">应用Key</param>
        /// <param name="appSecret">应用Secret</param>
        /// <param name="redirectUri">重定向URI</param>
        /// <returns>令牌响应</returns>
        private async Task<WeiboTokenResponse> GetWeiboAccessTokenAsync(string code, string appKey, string appSecret, string redirectUri)
        {
            try
            {
                var tokenUrl = "https://api.weibo.com/oauth2/access_token";

                var parameters = new Dictionary<string, string>
                {
                    ["client_id"] = appKey,
                    ["client_secret"] = appSecret,
                    ["grant_type"] = "authorization_code",
                    ["code"] = code,
                    ["redirect_uri"] = redirectUri ?? ""
                };

                var content = new FormUrlEncodedContent(parameters);
                var response = await _httpClient.PostAsync(tokenUrl, content);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取微博访问令牌失败: {response.StatusCode}, {errorContent}");
                }

                var jsonContent = await response.Content.ReadAsStringAsync();
                var tokenResponse = JsonSerializer.Deserialize<WeiboTokenResponse>(jsonContent, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
                });

                if (tokenResponse == null || string.IsNullOrEmpty(tokenResponse.AccessToken))
                {
                    throw new InvalidOperationException("获取微博访问令牌失败: 响应格式无效");
                }

                return tokenResponse;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取微博访问令牌失败");
                throw;
            }
        }

        /// <summary>
        /// 获取微博用户信息
        /// </summary>
        /// <param name="accessToken">访问令牌</param>
        /// <param name="uid">用户ID</param>
        /// <returns>用户信息</returns>
        private async Task<WeiboUserInfo> GetWeiboUserInfoAsync(string accessToken, string uid)
        {
            try
            {
                var userInfoUrl = $"https://api.weibo.com/2/users/show.json?access_token={accessToken}&uid={uid}";

                var response = await _httpClient.GetAsync(userInfoUrl);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取微博用户信息失败: {response.StatusCode}, {errorContent}");
                }

                var jsonContent = await response.Content.ReadAsStringAsync();
                var userInfo = JsonSerializer.Deserialize<WeiboUserInfo>(jsonContent, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
                });

                if (userInfo == null)
                {
                    throw new InvalidOperationException("获取微博用户信息失败: 响应格式无效");
                }

                return userInfo;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取微博用户信息失败");
                throw;
            }
        }

        /// <summary>
        /// 获取钉钉访问令牌
        /// </summary>
        /// <param name="code">授权码</param>
        /// <param name="appKey">应用Key</param>
        /// <param name="appSecret">应用Secret</param>
        /// <param name="redirectUri">重定向URI</param>
        /// <returns>访问令牌</returns>
        private async Task<string> GetDingTalkAccessTokenAsync(string code, string appKey, string appSecret, string redirectUri)
        {
            try
            {
                // 第一步：获取应用访问令牌
                var appTokenUrl = "https://oapi.dingtalk.com/gettoken";
                var appTokenResponse = await _httpClient.GetAsync($"{appTokenUrl}?appkey={appKey}&appsecret={appSecret}");

                if (!appTokenResponse.IsSuccessStatusCode)
                {
                    throw new InvalidOperationException("获取钉钉应用令牌失败");
                }

                var appTokenContent = await appTokenResponse.Content.ReadAsStringAsync();
                var appTokenResult = JsonSerializer.Deserialize<DingTalkTokenResponse>(appTokenContent);

                if (appTokenResult?.ErrCode != 0 || string.IsNullOrEmpty(appTokenResult.AccessToken))
                {
                    throw new InvalidOperationException($"获取钉钉应用令牌失败: {appTokenResult?.ErrMsg}");
                }

                // 第二步：使用授权码获取用户访问令牌
                var userTokenUrl = "https://oapi.dingtalk.com/sns/getuserinfo_bycode";
                var userTokenRequest = new
                {
                    tmp_auth_code = code
                };

                var userTokenContent = new StringContent(
                    JsonSerializer.Serialize(userTokenRequest),
                    System.Text.Encoding.UTF8,
                    "application/json"
                );

                var userTokenResponse = await _httpClient.PostAsync(
                    $"{userTokenUrl}?access_token={appTokenResult.AccessToken}",
                    userTokenContent
                );

                if (!userTokenResponse.IsSuccessStatusCode)
                {
                    throw new InvalidOperationException("获取钉钉用户信息失败");
                }

                return appTokenResult.AccessToken;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取钉钉访问令牌失败");
                throw;
            }
        }

        /// <summary>
        /// 获取钉钉用户信息
        /// </summary>
        /// <param name="accessToken">访问令牌</param>
        /// <param name="appKey">应用Key</param>
        /// <param name="appSecret">应用Secret</param>
        /// <returns>用户信息</returns>
        private async Task<DingTalkUserInfo> GetDingTalkUserInfoAsync(string accessToken, string appKey, string appSecret)
        {
            try
            {
                // 这是一个简化的实现，实际的钉钉OAuth流程更复杂
                // 需要根据具体的钉钉API文档进行实现
                await Task.CompletedTask; // 添加await以修复警告

                return new DingTalkUserInfo
                {
                    OpenId = $"dingtalk_openid_{DateTime.UtcNow.Ticks}",
                    Name = "钉钉用户",
                    Avatar = ""
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取钉钉用户信息失败");
                throw;
            }
        }

        /// <summary>
        /// 生成JWT令牌
        /// </summary>
        /// <param name="provider">社交平台提供商</param>
        /// <param name="nickname">用户昵称</param>
        /// <param name="openId">第三方平台openId</param>
        /// <returns>JWT令牌</returns>
        private string GenerateJwtToken(string provider, string nickname, string openId)
        {
            // 简化实现，实际项目中应该使用JwtSecurityTokenHandler生成真实的JWT令牌
            var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            return $"jwt_{provider}_{nickname}_{openId}_{timestamp}";
        }

        /// <summary>
        /// 绑定GitHub账户
        /// </summary>
        /// <param name="code">授权码</param>
        /// <returns>绑定结果</returns>
        private async Task<string> BindGithubAccountAsync(string code)
        {
            try
            {
                var clientId = _configuration.GetValue<string>("Social:GitHub:ClientId");
                var clientSecret = _configuration.GetValue<string>("Social:GitHub:ClientSecret");

                if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret))
                {
                    throw new InvalidOperationException("GitHub OAuth配置不完整");
                }

                // 获取GitHub用户信息
                var tokenResponse = await GetGithubAccessTokenAsync(code, clientId, clientSecret);
                var userInfo = await GetGithubUserInfoAsync(tokenResponse.AccessToken);

                // 这里应该将用户信息保存到数据库，建立绑定关系
                _logger.LogInformation("GitHub账号绑定成功，用户: {Login}", userInfo.Login);

                return $"GitHub 账号 {userInfo.Login} 绑定成功";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "绑定GitHub账户失败");
                return "GitHub 账号绑定失败";
            }
        }

        /// <summary>
        /// 绑定Google账户
        /// </summary>
        /// <param name="code">授权码</param>
        /// <returns>绑定结果</returns>
        private async Task<string> BindGoogleAccountAsync(string code)
        {
            try
            {
                var clientId = _configuration.GetValue<string>("Social:Google:ClientId");
                var clientSecret = _configuration.GetValue<string>("Social:Google:ClientSecret");
                var redirectUri = _configuration.GetValue<string>("Social:Google:RedirectUri");

                if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret))
                {
                    throw new InvalidOperationException("Google OAuth配置不完整");
                }

                // 获取Google用户信息
                var tokenResponse = await GetGoogleAccessTokenAsync(code, clientId, clientSecret, redirectUri ?? "");
                var userInfo = await GetGoogleUserInfoAsync(tokenResponse.AccessToken);

                // 这里应该将用户信息保存到数据库，建立绑定关系
                _logger.LogInformation("Google账号绑定成功，用户: {Name}", userInfo.Name);

                return $"Google 账号 {userInfo.Name} 绑定成功";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "绑定Google账户失败");
                return "Google 账号绑定失败";
            }
        }

        /// <summary>
        /// 绑定微博账户
        /// </summary>
        /// <param name="code">授权码</param>
        /// <returns>绑定结果</returns>
        private async Task<string> BindWeiboAccountAsync(string code)
        {
            try
            {
                var appKey = _configuration.GetValue<string>("Social:Weibo:AppKey");
                var appSecret = _configuration.GetValue<string>("Social:Weibo:AppSecret");
                var redirectUri = _configuration.GetValue<string>("Social:Weibo:RedirectUri");

                if (string.IsNullOrEmpty(appKey) || string.IsNullOrEmpty(appSecret))
                {
                    throw new InvalidOperationException("微博OAuth配置不完整");
                }

                // 获取微博用户信息
                var tokenResponse = await GetWeiboAccessTokenAsync(code, appKey, appSecret, redirectUri ?? "");
                var userInfo = await GetWeiboUserInfoAsync(tokenResponse.AccessToken, tokenResponse.Uid);

                // 这里应该将用户信息保存到数据库，建立绑定关系
                _logger.LogInformation("微博账号绑定成功，用户: {ScreenName}", userInfo.ScreenName);

                return $"微博 账号 {userInfo.ScreenName} 绑定成功";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "绑定微博账户失败");
                return "微博 账号绑定失败";
            }
        }

        /// <summary>
        /// 绑定钉钉账户
        /// </summary>
        /// <param name="code">授权码</param>
        /// <returns>绑定结果</returns>
        private async Task<string> BindDingTalkAccountAsync(string code)
        {
            try
            {
                var appKey = _configuration.GetValue<string>("Social:DingTalk:AppKey");
                var appSecret = _configuration.GetValue<string>("Social:DingTalk:AppSecret");
                var redirectUri = _configuration.GetValue<string>("Social:DingTalk:RedirectUri");

                if (string.IsNullOrEmpty(appKey) || string.IsNullOrEmpty(appSecret))
                {
                    throw new InvalidOperationException("钉钉OAuth配置不完整");
                }

                // 获取钉钉用户信息
                var accessToken = await GetDingTalkAccessTokenAsync(code, appKey, appSecret, redirectUri ?? "");
                var userInfo = await GetDingTalkUserInfoAsync(accessToken, appKey, appSecret);

                // 这里应该将用户信息保存到数据库，建立绑定关系
                _logger.LogInformation("钉钉账号绑定成功，用户: {Name}", userInfo.Name);

                return $"钉钉 账号 {userInfo.Name} 绑定成功";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "绑定钉钉账户失败");
                return "钉钉 账号绑定失败";
            }
        }

        /// <summary>
        /// 绑定微信账户
        /// </summary>
        /// <param name="code">授权码</param>
        /// <returns>绑定结果</returns>
        private async Task<string> BindWeChatAccountAsync(string code)
        {
            try
            {
                var appId = _configuration.GetValue<string>("Social:WeChat:AppId");
                var appSecret = _configuration.GetValue<string>("Social:WeChat:AppSecret");

                if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(appSecret))
                {
                    throw new InvalidOperationException("微信OAuth配置不完整");
                }

                // 获取微信用户信息
                var tokenResponse = await GetWeChatAccessTokenAsync(code, appId, appSecret);
                var userInfo = await GetWeChatUserInfoAsync(tokenResponse.AccessToken, tokenResponse.OpenId);

                // 这里应该将用户信息保存到数据库，建立绑定关系
                _logger.LogInformation("微信账号绑定成功，用户: {Nickname}", userInfo.Nickname);

                return $"微信 账号 {userInfo.Nickname} 绑定成功";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "绑定微信账户失败");
                return "微信 账号绑定失败";
            }
        }

        /// <summary>
        /// 绑定QQ账户
        /// </summary>
        /// <param name="code">授权码</param>
        /// <returns>绑定结果</returns>
        private async Task<string> BindQQAccountAsync(string code)
        {
            try
            {
                var appId = _configuration.GetValue<string>("Social:QQ:AppId");
                var appKey = _configuration.GetValue<string>("Social:QQ:AppKey");
                var redirectUri = _configuration.GetValue<string>("Social:QQ:RedirectUri");

                if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(appKey))
                {
                    throw new InvalidOperationException("QQ OAuth配置不完整");
                }

                // 获取QQ用户信息
                var tokenResponse = await GetQQAccessTokenAsync(code, appId, appKey, redirectUri ?? "");
                var openId = await GetQQOpenIdAsync(tokenResponse.AccessToken);
                var userInfo = await GetQQUserInfoAsync(tokenResponse.AccessToken, appId, openId);

                // 这里应该将用户信息保存到数据库，建立绑定关系
                _logger.LogInformation("QQ账号绑定成功，用户: {Nickname}", userInfo.Nickname);

                return $"QQ 账号 {userInfo.Nickname} 绑定成功";
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "绑定QQ账户失败");
                return "QQ 账号绑定失败";
            }
        }

        /// <summary>
        /// 获取微信访问令牌
        /// </summary>
        /// <param name="code">授权码</param>
        /// <param name="appId">应用ID</param>
        /// <param name="appSecret">应用密钥</param>
        /// <returns>访问令牌响应</returns>
        private async Task<WeChatTokenResponse> GetWeChatAccessTokenAsync(string code, string appId, string appSecret)
        {
            try
            {
                var tokenUrl = $"https://api.weixin.qq.com/sns/oauth2/access_token?appid={appId}&secret={appSecret}&code={code}&grant_type=authorization_code";

                var response = await _httpClient.GetAsync(tokenUrl);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取微信访问令牌失败: {response.StatusCode}, {errorContent}");
                }

                var jsonContent = await response.Content.ReadAsStringAsync();
                var tokenResponse = JsonSerializer.Deserialize<WeChatTokenResponse>(jsonContent, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
                });

                if (tokenResponse == null || string.IsNullOrEmpty(tokenResponse.AccessToken))
                {
                    throw new InvalidOperationException("获取微信访问令牌失败: 响应格式无效");
                }

                return tokenResponse;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取微信访问令牌失败");
                throw;
            }
        }

        /// <summary>
        /// 获取微信用户信息
        /// </summary>
        /// <param name="accessToken">访问令牌</param>
        /// <param name="openId">OpenID</param>
        /// <returns>用户信息</returns>
        private async Task<WeChatUserInfo> GetWeChatUserInfoAsync(string accessToken, string openId)
        {
            try
            {
                var userInfoUrl = $"https://api.weixin.qq.com/sns/userinfo?access_token={accessToken}&openid={openId}&lang=zh_CN";

                var response = await _httpClient.GetAsync(userInfoUrl);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取微信用户信息失败: {response.StatusCode}, {errorContent}");
                }

                var jsonContent = await response.Content.ReadAsStringAsync();
                var userInfo = JsonSerializer.Deserialize<WeChatUserInfo>(jsonContent, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
                });

                if (userInfo == null)
                {
                    throw new InvalidOperationException("获取微信用户信息失败: 响应格式无效");
                }

                return userInfo;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取微信用户信息失败");
                throw;
            }
        }

        /// <summary>
        /// 获取QQ访问令牌
        /// </summary>
        /// <param name="code">授权码</param>
        /// <param name="appId">应用ID</param>
        /// <param name="appKey">应用Key</param>
        /// <param name="redirectUri">重定向URI</param>
        /// <returns>访问令牌响应</returns>
        private async Task<QQTokenResponse> GetQQAccessTokenAsync(string code, string appId, string appKey, string redirectUri)
        {
            try
            {
                var tokenUrl = "https://graph.qq.com/oauth2.0/token";
                var queryString = $"grant_type=authorization_code&client_id={appId}&client_secret={appKey}&code={code}&redirect_uri={Uri.EscapeDataString(redirectUri)}";

                var response = await _httpClient.GetAsync($"{tokenUrl}?{queryString}");

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取QQ访问令牌失败: {response.StatusCode}, {errorContent}");
                }

                var content = await response.Content.ReadAsStringAsync();

                // QQ返回的是URL编码格式，需要解析
                var result = new QQTokenResponse();
                var parts = content.Split('&');
                foreach (var part in parts)
                {
                    var keyValue = part.Split('=');
                    if (keyValue.Length == 2)
                    {
                        if (keyValue[0] == "access_token")
                            result.AccessToken = keyValue[1];
                        else if (keyValue[0] == "expires_in")
                            result.ExpiresIn = int.Parse(keyValue[1]);
                        else if (keyValue[0] == "refresh_token")
                            result.RefreshToken = keyValue[1];
                    }
                }

                if (string.IsNullOrEmpty(result.AccessToken))
                {
                    throw new InvalidOperationException("获取QQ访问令牌失败: 响应格式无效");
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取QQ访问令牌失败");
                throw;
            }
        }

        /// <summary>
        /// 获取QQ OpenID
        /// </summary>
        /// <param name="accessToken">访问令牌</param>
        /// <returns>OpenID</returns>
        private async Task<string> GetQQOpenIdAsync(string accessToken)
        {
            try
            {
                var openIdUrl = $"https://graph.qq.com/oauth2.0/me?access_token={accessToken}";

                var response = await _httpClient.GetAsync(openIdUrl);

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取QQ OpenID失败: {response.StatusCode}, {errorContent}");
                }

                var content = await response.Content.ReadAsStringAsync();

                // QQ返回的是JSONP格式，需要提取JSON部分
                var jsonStart = content.IndexOf('{');
                var jsonEnd = content.LastIndexOf('}');

                if (jsonStart >= 0 && jsonEnd >= 0)
                {
                    var json = content.Substring(jsonStart, jsonEnd - jsonStart + 1);
                    var openIdResponse = JsonSerializer.Deserialize<QQOpenIdResponse>(json);

                    if (openIdResponse != null && !string.IsNullOrEmpty(openIdResponse.OpenId))
                    {
                        return openIdResponse.OpenId;
                    }
                }

                throw new InvalidOperationException("获取QQ OpenID失败: 响应格式无效");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取QQ OpenID失败");
                throw;
            }
        }

        /// <summary>
        /// 获取QQ用户信息
        /// </summary>
        /// <param name="accessToken">访问令牌</param>
        /// <param name="appId">应用ID</param>
        /// <param name="openId">OpenID</param>
        /// <returns>用户信息</returns>
        private async Task<QQUserInfo> GetQQUserInfoAsync(string accessToken, string appId, string openId)
        {
            try
            {
                var userInfoUrl = "https://graph.qq.com/user/get_user_info";
                var queryString = $"access_token={accessToken}&oauth_consumer_key={appId}&openid={openId}";

                var response = await _httpClient.GetAsync($"{userInfoUrl}?{queryString}");

                if (!response.IsSuccessStatusCode)
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    throw new InvalidOperationException($"获取QQ用户信息失败: {response.StatusCode}, {errorContent}");
                }

                var jsonContent = await response.Content.ReadAsStringAsync();
                var userInfo = JsonSerializer.Deserialize<QQUserInfo>(jsonContent);

                if (userInfo == null || userInfo.Ret != 0)
                {
                    throw new InvalidOperationException($"获取QQ用户信息失败: {userInfo?.Msg ?? "响应格式无效"}");
                }

                return userInfo;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取QQ用户信息失败");
                throw;
            }
        }

        #endregion

   

    #region 数据模型

    /// <summary>
    /// 微博访问令牌响应模型
    /// </summary>
    private class WeiboTokenResponse
    {
        public string AccessToken { get; set; } = string.Empty;
        public string Uid { get; set; } = string.Empty;
        public int ExpiresIn { get; set; }
        public string? RefreshToken { get; set; }
    }

    /// <summary>
    /// 微博用户信息模型
    /// </summary>
    private class WeiboUserInfo
    {
        public string Id { get; set; } = string.Empty;
        public string ScreenName { get; set; } = string.Empty;
        public string Name { get; set; } = string.Empty;
        public string ProfileImageUrl { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
    }

    /// <summary>
    /// 钉钉访问令牌响应模型
    /// </summary>
    private class DingTalkTokenResponse
    {
        public int ErrCode { get; set; }
        public string? ErrMsg { get; set; }
        public string AccessToken { get; set; } = string.Empty;
        public int ExpiresIn { get; set; }
    }

    /// <summary>
    /// 钉钉用户信息模型
    /// </summary>
    private class DingTalkUserInfo
    {
        public string OpenId { get; set; } = string.Empty;
        public string Name { get; set; } = string.Empty;
        public string Avatar { get; set; } = string.Empty;
    }

    /// <summary>
    /// 微信访问令牌响应模型
    /// </summary>
    private class WeChatTokenResponse
    {
        public string AccessToken { get; set; } = string.Empty;
        public string OpenId { get; set; } = string.Empty;
        public int ExpiresIn { get; set; }
        public string RefreshToken { get; set; } = string.Empty;
        public string Scope { get; set; } = string.Empty;
    }

    /// <summary>
    /// 微信用户信息模型
    /// </summary>
    private class WeChatUserInfo
    {
        public string OpenId { get; set; } = string.Empty;
        public string Nickname { get; set; } = string.Empty;
        public int Sex { get; set; }
        public string Province { get; set; } = string.Empty;
        public string City { get; set; } = string.Empty;
        public string Country { get; set; } = string.Empty;
        public string HeadImgUrl { get; set; } = string.Empty;
        public string UnionId { get; set; } = string.Empty;
    }

    /// <summary>
    /// QQ访问令牌响应模型
    /// </summary>
    private class QQTokenResponse
    {
        public string AccessToken { get; set; } = string.Empty;
        public int ExpiresIn { get; set; }
        public string RefreshToken { get; set; } = string.Empty;
    }

    /// <summary>
    /// QQ OpenID响应模型
    /// </summary>
    private class QQOpenIdResponse
    {
        public string ClientId { get; set; } = string.Empty;
        public string OpenId { get; set; } = string.Empty;
    }

    /// <summary>
    /// QQ用户信息模型
    /// </summary>
    private class QQUserInfo
    {
        public int Ret { get; set; }
        public string Msg { get; set; } = string.Empty;
        public string Nickname { get; set; } = string.Empty;
        public string FigureUrl { get; set; } = string.Empty;
        public string FigureUrl1 { get; set; } = string.Empty;
        public string FigureUrl2 { get; set; } = string.Empty;
        public string FigureUrlQq1 { get; set; } = string.Empty;
        public string FigureUrlQq2 { get; set; } = string.Empty;
        public string Gender { get; set; } = string.Empty;
    }

    /// <summary>
    /// GitHub访问令牌响应模型
    /// </summary>
    private class GitHubTokenResponse
    {
        public string AccessToken { get; set; } = string.Empty;
        public string TokenType { get; set; } = string.Empty;
        public string Scope { get; set; } = string.Empty;
    }

    /// <summary>
    /// GitHub用户信息模型
    /// </summary>
    private class GitHubUserInfo
    {
        public long Id { get; set; }
        public string Login { get; set; } = string.Empty;
        public string AvatarUrl { get; set; } = string.Empty;
        public string Name { get; set; } = string.Empty;
        public string Email { get; set; } = string.Empty;
    }

    /// <summary>
    /// Google访问令牌响应模型
    /// </summary>
    private class GoogleTokenResponse
    {
        public string AccessToken { get; set; } = string.Empty;
        public int ExpiresIn { get; set; }
        public string RefreshToken { get; set; } = string.Empty;
        public string TokenType { get; set; } = string.Empty;
        public string IdToken { get; set; } = string.Empty;
    }

    /// <summary>
    /// Google用户信息模型
    /// </summary>
    private class GoogleUserInfo
    {
        public string Id { get; set; } = string.Empty;
        public string Email { get; set; } = string.Empty;
        public bool VerifiedEmail { get; set; }
        public string Name { get; set; } = string.Empty;
        public string GivenName { get; set; } = string.Empty;
        public string FamilyName { get; set; } = string.Empty;
        public string Picture { get; set; } = string.Empty;
        public string Locale { get; set; } = string.Empty;
    }
}
    #endregion
 
}

